home *** CD-ROM | disk | FTP | other *** search
- program TwrHanoi;
-
- {$IFDEF Win32}
- {$APPTYPE CONSOLE}
- {$ENDIF}
-
- uses
- {$IFDEF Win32}
- Windows,
- {$ELSE}
- WinCRT, WinTypes, WinProcs,
- {$ENDIF}
- SysUtils;
-
- var
- MoveCount : integer;
-
- procedure StackHanoi(N : byte; FromPole, ToPole, SparePole : char);
- {move N disks from FromPole to ToPole using SparePole as a spare}
- type
- TParam = record
- pN : byte;
- pFrom, pTo, pSpare : char;
- end;
- var
- Stack : array [0..127] of TParam;
- SP : integer;
- P : TParam;
- begin
- {clear the stack}
- SP := 0;
- {push our parameters onto the stack}
- with Stack[SP] do begin
- pn := N; pFrom := FromPole; pTo := ToPole; pSpare := SparePole;
- end;
- inc(SP);
- {while the stack is not empty...}
- while (SP <> 0) do begin
- {pop the stack}
- dec(SP);
- longint(P) := longint(Stack[SP]);
- {if the disk number is 1, or it's a move, move it}
- if (P.pN = 1) or (P.pSpare = #0) then begin
- inc(MoveCount);
- writeln('Move disk ', P.pN, ' from ', P.pFrom, ' to ', P.pTo);
- end
- else begin
- {push the parameters to move N-1 disks from Spare to To}
- with Stack[SP] do begin
- pN := P.pN - 1;
- pFrom := P.pSpare; pTo := P.pTo; pSpare := P.pFrom;
- end;
- inc(SP);
- {push the parameters for the move}
- with Stack[SP] do begin
- pn := P.pN;
- pFrom := P.pFrom; pTo := P.pTo; pSpare := #0;
- end;
- inc(SP);
- {push the parameters to move N-1 disks from From to Spare}
- with Stack[SP] do begin
- pn := P.pN - 1;
- pFrom := P.pFrom; pTo := P.pSpare; pSpare := P.pTo;
- end;
- inc(SP);
- end;
- end;
- end;
-
- procedure FastHanoi(N : integer; FromPole, ToPole, SparePole : char);
- {move N disks from FromPole to ToPole using SparePole as a spare}
- var
- Finished : boolean;
- Temp : char;
- begin
- Finished := false;
- while not Finished do begin
- {if there's just one disk, move it}
- if (N = 1) then begin
- inc(MoveCount);
- writeln('Move disk ', N, ' from ', FromPole, ' to ', ToPole);
- Finished := true;
- end
- else {move more than one disk} begin
- {First: move N-1 disks to SparePole, using ToPole as the spare}
- FastHanoi(N-1, FromPole, SparePole, ToPole);
- {Second: move the Nth disk}
- inc(MoveCount);
- writeln('Move disk ', N, ' from ', FromPole, ' to ', ToPole);
- {Last: move N-1 disks from SparePole to ToPole, using FromPole as
- the spare}
- dec(N);
- Temp := SparePole;
- SparePole := FromPole;
- FromPole := Temp;
- end;
- end;
- end;
-
- procedure Hanoi(N : integer; FromPole, ToPole, SparePole : char);
- {move N disks from FromPole to ToPole using SparePole as a spare}
- begin
- {if there's just one disk, move it}
- if (N = 1) then begin
- inc(MoveCount);
- writeln('Move disk ', N, ' from ', FromPole, ' to ', ToPole);
- end
- else {move more than one disk} begin
- {First: move N-1 disks to SparePole, using ToPole as the spare}
- Hanoi(N-1, FromPole, SparePole, ToPole);
- {Second: move the Nth disk}
- inc(MoveCount);
- writeln('Move disk ', N, ' from ', FromPole, ' to ', ToPole);
- {Last: move N-1 disks from SparePole to ToPole, using FromPole as
- the spare}
- Hanoi(N-1, SparePole, ToPole, FromPole);
- end;
- end;
-
- var
- EndTime, StartTime : integer;
- DiskCount : integer;
- AvePerMove : double;
-
- begin
- MoveCount := 0;
- DiskCount := 10;
- StartTime := GetTickCount;
- StackHanoi(DiskCount, 'A', 'B', 'C');
- EndTime := GetTickCount;
- writeln('Number of disks: ', DiskCount);
- writeln('Number of moves: ', MoveCount);
- writeln('Time taken: ', EndTime - StartTime);
- AvePerMove := (EndTime - StartTime) / MoveCount;
- writeln('Average milliseconds per move: ', AvePerMove:15:9);
- writeln('Time in years to do 64 disks: ', AvePerMove * 1.844674407371e+19 /
- (1000 * 60 * 60 * 24 * 365.25):15:5);
- readln;
- end.
-